package ai.hou.camera;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.util.Size;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.camera2.Camera2Config;
import androidx.camera.core.AspectRatio;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.TorchState;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Locale;

import ai.hou.camera.util.CameraConfig;
import ai.hou.camera.util.IntentUtils;
import ai.hou.camera.util.RealPathFromUriUtils;
import ai.hou.camera.util.ZxingUtils;
import ai.hou.camera.view.MagicCameraView;
import ai.hou.camera.view.MagicCropView;
import ai.hou.camera.view.MagicMaskView;
import ai.hou.camera.view.ScanTipView;


/**
 * 相机
 * <p>
 * Use {@link ai.hou.camera.util.CameraConfig#INTENT_CAMERA} enter.
 *
 * @author zhaoxiaolei
 */
public class CameraActivity extends AppCompatActivity implements CameraXConfig.Provider {
    private static final String TAG = "CameraActivity";

    /**
     * 相机权限申请码
     */
    public static final int PERMISSION_REQUEST_CODE_CAMERA = 101;
    /**
     * 照片存储申请码
     */
    public static final int PERMISSION_REQUEST_CODE_STORAGE = 102;
    /**
     * 照相机
     */
    private MagicCameraView mCameraView;
    /**
     * 扫描提示
     */
    private ScanTipView mScanTipView;
    /**
     * 遮罩
     */
    private MagicMaskView mMaskView;
    /**
     * 裁剪
     */
    private MagicCropView mCropView;
    //控制按钮
    /**
     * 顶部按钮
     */
    private View topController;
    /**
     * 比例
     */
    private ImageView ivAspectRatio;
    /**
     * 选择比例
     */
    private ViewGroup vgAspectRatio;
    private ImageView iv43;
    private ImageView iv169;
    private ImageView iv11;
    /**
     * 开关灯按钮
     */
    private ImageView ivTorch;
    /**
     * 闪光灯模式
     */
    private ImageView ivFlashMode;
    /**
     * 选择闪光灯模式
     */
    private ViewGroup vgFlashMode;
    private ImageView ivFlashModeOff;
    private ImageView ivFlashModeAuto;
    private ImageView ivFlashModeOn;

    /**
     * 裁剪控制按钮
     */
    private View cropLayout;
    private ImageView ivCropReset;
    private ImageView ivCropDone;
    private ImageView ivCropClose;

    /**
     * 控制布局背景
     */
    private View controllerBg;
    /**
     * 拍照按钮
     */
    private ImageView btnCapture;
    /**
     * 相册选择
     */
    private ImageView ivAlbum;
    /**
     * 缩放按钮
     */
    private TextView tvZoom;
    /**
     * 翻转相机
     */
    private ImageView ivOverturn;
    /**
     * 缩放 1x 和 2x
     */
    private int zoom;

    //以下是intent传递进入的参数
    /**
     * 是否需要切换相机尺寸比例
     */
    private boolean needAspectRatio;
    /**
     * 是否需要切换闪光灯模式
     */
    private boolean needFlashMode;
    /**
     * 闪光灯模式
     * {@link CameraConfig#FLASH_MODE_AUTO}
     * {@link CameraConfig#FLASH_MODE_OFF}
     * {@link CameraConfig#FLASH_MODE_ON}
     */
    private int flashMode;
    /**
     * 是否需要光
     */
    private boolean needTorch;
    /**
     * 是否需要切换摄像头
     */
    private boolean needTurnover;
    /**
     * 默认使用哪个摄像头
     * 1: 后置摄像头，0：前置摄像头
     */
    private int frontOrBackCamera = CameraSelector.LENS_FACING_BACK;
    /**
     * 是否需要缩放按钮
     */
    private boolean needZoom;
    /**
     * 是否需要跳转相册
     */
    private boolean needAlbum;
    /**
     * 是否需要MaskView
     */
    private boolean needMaskView;
    /**
     * MaskView的type
     * {@link MagicMaskView#MASK_NONE}, 啥都没有
     * {@link MagicMaskView#MASK_CUSTOM}, 自定义，需要传入drawable和尺寸
     * {@link MagicMaskView#MASK_ID_CARD_FRONT}, 身份证国徽面
     * {@link MagicMaskView#MASK_ID_CARD_BACK}， 身份证人像面
     * {@link MagicMaskView#MASK_STANDARD_CARD}  标准卡片，只有个卡片框，多用于银行卡等
     */
    private int maskType;
    /**
     * 是否需要CropView
     */
    private boolean needCropView;
    /**
     * 是否直接保存
     */
    private boolean saveDirectly;
    /**
     * 保存的文件路径
     */
    private String picturePath;
    /**
     * 是否支持二维码识别（直接扫码，暂时不支持相册选择识别）
     */
    private boolean supportScanQrCode;
    /**
     * 是否有白内障
     */
    private boolean hasCataract;
    /**
     * 白内障颜色
     */
    private int cataractColor;
    /**
     * 是否允许拖动裁剪框
     */
    private boolean dragCropEnable;
    private boolean qrCodeBack;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        initParam();

        findViews();

        cameraTask();
    }

    private void initParam() {
        Intent it = getIntent();
        needAspectRatio = it.getBooleanExtra(CameraConfig.EXTRA_ASPECT_RATIO, true);
        needFlashMode = it.getBooleanExtra(CameraConfig.EXTRA_HAS_FLASH_MODE, true);
        flashMode = it.getIntExtra(CameraConfig.EXTRA_FLASH_MODE, CameraConfig.FLASH_MODE_AUTO);
        needTorch = it.getBooleanExtra(CameraConfig.EXTRA_TORCH, true);
        needTurnover = it.getBooleanExtra(CameraConfig.EXTRA_TURNOVER, true);
        frontOrBackCamera = it.getIntExtra(CameraConfig.EXTRA_FRONT_BACK_CAMERA, CameraConfig.LENS_FACING_BACK);
        needZoom = it.getBooleanExtra(CameraConfig.EXTRA_SUPPORT_ZOOM, true);
        needAlbum = it.getBooleanExtra(CameraConfig.EXTRA_HAS_ALBUM, true);
        needMaskView = it.getBooleanExtra(CameraConfig.EXTRA_HAS_MASK_VIEW, false);
        maskType = it.getIntExtra(CameraConfig.EXTRA_MASK_TYPE, CameraConfig.MASK_NONE);
        needCropView = it.getBooleanExtra(CameraConfig.EXTRA_HAS_CROP_VIEW, false);
        saveDirectly = it.getBooleanExtra(CameraConfig.EXTRA_SAVE_DIRECTLY, false);
        picturePath = it.getStringExtra(CameraConfig.EXTRA_PICTURE_PATH);
        supportScanQrCode = it.getBooleanExtra(CameraConfig.EXTRA_SUPPORT_SCAN_QR_CODE, false);
        hasCataract = it.getBooleanExtra(CameraConfig.EXTRA_HAS_CATARACT, false);
        cataractColor = it.getIntExtra(CameraConfig.EXTRA_CATARACT_COLOR, 0);
        dragCropEnable = it.getBooleanExtra(CameraConfig.EXTRA_DRAG_CROP_ENABLE, true);
        qrCodeBack = it.getBooleanExtra(CameraConfig.EXTRA_QR_CODE_BACK, false);
    }

    private void findViews() {
        btnCapture = findViewById(R.id.camera_capture_button);
        ivTorch = findViewById(R.id.iv_flashlight);
        tvZoom = findViewById(R.id.tv_zoom);
        ivOverturn = findViewById(R.id.iv_overturn);
        topController = findViewById(R.id.top_controller);
        ivAspectRatio = findViewById(R.id.iv_aspect_ratio);
        ivFlashMode = findViewById(R.id.iv_flash_mode);
        vgAspectRatio = findViewById(R.id.vg_aspect_ratio);
        vgFlashMode = findViewById(R.id.vg_flash_mode);
        iv43 = findViewById(R.id.iv_4_3);
        iv169 = findViewById(R.id.iv_16_9);
        iv11 = findViewById(R.id.iv_1_1);
        ivFlashModeOff = findViewById(R.id.iv_flash_mode_off);
        ivFlashModeAuto = findViewById(R.id.iv_flash_mode_auto);
        ivFlashModeOn = findViewById(R.id.iv_flash_mode_on);
        controllerBg = findViewById(R.id.controller_bg);
        mCameraView = findViewById(R.id.cameraView);
        mScanTipView = findViewById(R.id.scanTipView);
        mMaskView = findViewById(R.id.maskView);
        mCropView = findViewById(R.id.cropView);
        cropLayout = findViewById(R.id.crop_layout);
        ivCropReset = findViewById(R.id.crop_reset);
        ivCropDone = findViewById(R.id.crop_done);
        ivCropClose = findViewById(R.id.crop_close);
        ivAlbum = findViewById(R.id.iv_gallery);
    }

    private void cameraTask() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA},
                    PERMISSION_REQUEST_CODE_CAMERA);
        } else {
            initView();
        }
    }

    private void takePictureTask() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
                    PERMISSION_REQUEST_CODE_STORAGE);
        } else {
            takePhoto();
        }
    }

    private void setViewVisible() {
        ivAspectRatio.setVisibility(needAspectRatio ? View.VISIBLE : View.GONE);
        ivFlashMode.setVisibility(needFlashMode ? View.VISIBLE : View.GONE);
        ivTorch.setVisibility(needTorch ? View.VISIBLE : View.GONE);
        ivOverturn.setVisibility(needTurnover ? View.VISIBLE : View.GONE);
        tvZoom.setVisibility(needZoom ? View.VISIBLE : View.GONE);
        ivAlbum.setVisibility(needAlbum ? View.VISIBLE : View.GONE);
        mMaskView.setVisibility(needMaskView ? View.VISIBLE : View.GONE);
    }

    private void initView() {
        setViewVisible();
        mCameraView.initCameraView();

        btnCapture.setOnClickListener(v -> takePictureTask());
        ivTorch.setOnClickListener(v -> mCameraView.toggleTorch());
        ivAlbum.setOnClickListener(v -> {
            if (onGalleryListener != null) {
                onGalleryListener.onGallery();
            }
        });
        tvZoom.setOnClickListener(v -> {
            //zoom：0和1切换
            zoom ^= 1;
            mCameraView.setZoomRatio(zoom + 1);
        });
        ivOverturn.setOnClickListener(this::switchFrontBackCamera);
        ivAspectRatio.setOnClickListener(v -> {
            topController.setVisibility(View.INVISIBLE);
            vgAspectRatio.setVisibility(View.VISIBLE);
        });
        ivFlashMode.setOnClickListener(v -> {
            topController.setVisibility(View.INVISIBLE);
            vgFlashMode.setVisibility(View.VISIBLE);
        });
        iv43.setOnClickListener(v -> switchAspectRatio(CameraConfig.ASPECT_RATIO_4_3));
        iv169.setOnClickListener(v -> switchAspectRatio(CameraConfig.ASPECT_RATIO_16_9));
        iv11.setOnClickListener(v -> switchAspectRatio(CameraConfig.ASPECT_RATIO_1_1));
        ivFlashModeOff.setOnClickListener(v -> switchFlashMode(CameraConfig.FLASH_MODE_OFF));
        ivFlashModeAuto.setOnClickListener(v -> switchFlashMode(CameraConfig.FLASH_MODE_AUTO));
        ivFlashModeOn.setOnClickListener(v -> switchFlashMode(CameraConfig.FLASH_MODE_ON));
        ivCropReset.setOnClickListener(v -> {
            cropLayout.setVisibility(View.GONE);
            mCameraView.onCreate();
        });
        ivCropClose.setOnClickListener(v -> finish());
        ivCropDone.setOnClickListener(v -> {
            File cropFile;
            if (TextUtils.isEmpty(picturePath)) {
                File outputDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                cropFile = new File(
                        outputDirectory,
                        new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()
                        ).format(System.currentTimeMillis()) + ".jpg");
            } else {
                cropFile = new File(picturePath);
            }
            boolean crop = mCropView.cropToPicture(cropFile);
            if (crop) {
                mediaScanFile(cropFile, false);

                Intent intent = new Intent();
                intent.putExtra(CameraConfig.DATA_TAKE_PICTURE_PATH, cropFile.getAbsolutePath());
                intent.putExtra(CameraConfig.DATA_TAKE_TYPE, CameraConfig.DATA_TAKE_CAMERA);
                setResult(RESULT_OK, intent);
                finish();
            } else {
                showToast("图片保存失败，请重试");
            }
        });
        mCameraView.setOnClickListener(v -> {
            if (vgAspectRatio.getVisibility() == View.VISIBLE || vgFlashMode.getVisibility() == View.VISIBLE) {
                vgAspectRatio.setVisibility(View.GONE);
                vgFlashMode.setVisibility(View.GONE);
                topController.setVisibility(View.VISIBLE);
            }
        });
        mCameraView.setCallback(cameraInitCallback);
        if (supportScanQrCode) {
            mCameraView.setDecodeQrCodeListener(decodeQrCodeListener);
            mScanTipView.setVisibility(View.VISIBLE);
            mScanTipView.startScanTip();
        }
        mCameraView.requireLensFacing(frontOrBackCamera);

        mMaskView.setMaskType(maskType);
        //是否支持白内障
        mMaskView.setCataract(hasCataract);
        mMaskView.setCataractColor(cataractColor);
        mCropView.setCataract(hasCataract);
        mCropView.setCataractColor(cataractColor);
        mCropView.setDragCropEnable(dragCropEnable);
    }

    private void mediaScanFile(File file, boolean showThumb) {
        MediaScannerConnection.scanFile(
                CameraActivity.this,
                new String[]{file.getAbsolutePath()},
                new String[]{"image/jpeg"},
                (path, uri) ->
                        mCameraView.post(() -> {
//                                    showToast("保存到：" + photoFile.getAbsolutePath());
                                    if (showThumb) {
                                        ivAlbum.setImageURI(Uri.fromFile(file));
                                    }
                                }
                        )
        );
    }

    private void switchFrontBackCamera(View v) {
        v.animate().rotation((v.getRotation() + 180) % 360).setDuration(400).start();
        if (mCameraView.getLensFacing() == CameraSelector.LENS_FACING_BACK) {
            mCameraView.requireLensFacing(CameraSelector.LENS_FACING_FRONT);
        } else {
            mCameraView.requireLensFacing(CameraSelector.LENS_FACING_BACK);
        }
    }

    private void switchAspectRatio(int aspectRatioType) {
        iv43.setAlpha(0.5f);
        iv169.setAlpha(0.5f);
        iv11.setAlpha(0.5f);
        if (aspectRatioType == CameraConfig.ASPECT_RATIO_4_3) {
            iv43.setAlpha(1f);
            ivAspectRatio.setImageResource(R.drawable.ic_4_3);
            mCameraView.setIsCustomSize(false);
            mCameraView.setTargetAspectRatio(AspectRatio.RATIO_4_3);
            mCameraView.setPreviewGravity(Gravity.TOP);
            controllerBg.setVisibility(View.INVISIBLE);
        } else if (aspectRatioType == CameraConfig.ASPECT_RATIO_16_9) {
            iv169.setAlpha(1f);
            ivAspectRatio.setImageResource(R.drawable.ic_16_9);
            mCameraView.setIsCustomSize(false);
            mCameraView.setTargetAspectRatio(AspectRatio.RATIO_16_9);
            mCameraView.setPreviewGravity(Gravity.TOP);
            controllerBg.setVisibility(View.VISIBLE);
        } else if (aspectRatioType == CameraConfig.ASPECT_RATIO_1_1) {
            iv11.setAlpha(1f);
            ivAspectRatio.setImageResource(R.drawable.ic_1_1);
            mCameraView.setIsCustomSize(true);
            mCameraView.setCustomSize(mCameraView.getWidth(), mCameraView.getWidth());
            mCameraView.setPreviewGravity(Gravity.CENTER);
            controllerBg.setVisibility(View.INVISIBLE);
        }
        topController.setVisibility(View.VISIBLE);
        vgAspectRatio.setVisibility(View.GONE);
    }

    private void switchFlashMode(int flashMode) {
        ivFlashModeOff.setAlpha(0.5f);
        ivFlashModeAuto.setAlpha(0.5f);
        ivFlashModeOn.setAlpha(0.5f);
        if (flashMode == CameraConfig.FLASH_MODE_OFF) {
            ivFlashModeOff.setAlpha(1f);
            ivFlashMode.setImageResource(R.drawable.ic_flash_mode_off);
            mCameraView.setFlashMode(ImageCapture.FLASH_MODE_OFF);
        } else if (flashMode == CameraConfig.FLASH_MODE_AUTO) {
            ivFlashModeAuto.setAlpha(1f);
            ivFlashMode.setImageResource(R.drawable.ic_flash_mode_auto);
            mCameraView.setFlashMode(ImageCapture.FLASH_MODE_AUTO);
        } else if (flashMode == CameraConfig.FLASH_MODE_ON) {
            ivFlashModeOn.setAlpha(1f);
            ivFlashMode.setImageResource(R.drawable.ic_flash_mode_on);
            mCameraView.setFlashMode(ImageCapture.FLASH_MODE_ON);
        }
        topController.setVisibility(View.VISIBLE);
        vgFlashMode.setVisibility(View.GONE);
    }

    private final MagicCameraView.CameraInitCallback cameraInitCallback = () -> {
        ivTorch.setVisibility(needTorch && mCameraView.getCameraInfo().hasFlashUnit() ? View.VISIBLE : View.GONE);
        ivOverturn.setVisibility(needTurnover && mCameraView.hasFontCamera() && mCameraView.hasBackCamera() ? View.VISIBLE : View.GONE);
        mCameraView.setFlashMode(flashMode);
        mCameraView.getTorchState().observe(this, state -> {
            if (state == TorchState.ON) {
                ivTorch.setImageResource(R.drawable.ic_flashlight_on);
            } else {
                ivTorch.setImageResource(R.drawable.ic_flashlight_off);
            }
        });
        mCameraView.getZoomState().observe(this, state -> {
            float linearZoom = state.getLinearZoom();
            float zoomRatio = state.getZoomRatio();
            Log.d(TAG, "linearZoom: " + linearZoom + "==zoomRatio=" + zoomRatio);
            float ratio = new BigDecimal(zoomRatio).setScale(1, BigDecimal.ROUND_HALF_UP).floatValue();
            tvZoom.setText(String.format("%s X", ratio));
            if (state.getZoomRatio() == 1) {
                zoom = 0;
            } else {
                zoom = 1;
            }
        });
    };

    private final ZxingUtils.DecodeQrCodeListener decodeQrCodeListener = new ZxingUtils.DecodeQrCodeListener() {
        @Override
        public void onSuccess(String text) {
            if (qrCodeBack) {
                Intent intent = new Intent();
                intent.putExtra(CameraConfig.DATA_TAKE_TYPE, CameraConfig.DATA_TAKE_QR_CODE);
                intent.putExtra(CameraConfig.DATA_SCAN_QR_CODE_RESULT, text);
                setResult(RESULT_OK, intent);
                finish();
            } else {
                showDecodeQrCodeResult(text);
                mScanTipView.stopScanTip();
            }
        }

        @Override
        public void onFailed() {

        }
    };

    private void showDecodeQrCodeResult(String msg) {
        new AlertDialog.Builder(this)
                .setTitle("温馨提示")
                .setMessage(msg)
                .setPositiveButton("我知道了", (dialog, which) -> {
                    mCameraView.restartAnalyzer();
                    mScanTipView.startScanTip();
                })
                .show();
    }

    @NonNull
    @Override
    public CameraXConfig getCameraXConfig() {
        return Camera2Config.defaultConfig();
    }

    private void takePhoto() {
        if (saveDirectly) {
            File photoFile;
            if (TextUtils.isEmpty(picturePath)) {
                File outputDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                photoFile = new File(
                        outputDirectory,
                        new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()
                        ).format(System.currentTimeMillis()) + ".jpg");
            } else {
                photoFile = new File(picturePath);
            }

            mCameraView.takePicture(photoFile, new ImageCapture.OnImageSavedCallback() {
                @Override
                public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                    mediaScanFile(photoFile, true);

                    Intent intent = new Intent();
                    intent.putExtra(CameraConfig.DATA_TAKE_PICTURE_PATH, photoFile.getAbsolutePath());
                    intent.putExtra(CameraConfig.DATA_TAKE_TYPE, CameraConfig.DATA_TAKE_CAMERA);
                    setResult(RESULT_OK, intent);
                    finish();
                }

                @Override
                public void onError(@NonNull ImageCaptureException exception) {
                    exception.printStackTrace();
                    Log.d(TAG, "哎呀！不知怎么的拍失误了: " + exception.getMessage());
                    showToast("哎呀！不知怎么的拍失误了，再来一次吧~");
                }
            });
        } else {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            mCameraView.takePicture(stream, new ImageCapture.OnImageSavedCallback() {
                @Override
                public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                    mCameraView.onDestroy();
                    cropLayout.setVisibility(View.VISIBLE);
                    Size previewSize = mCameraView.getPreviewSize();
                    mCropView.setIsCropView(needCropView);
                    mCropView.setCropBounds(mMaskView.getBgBound());
                    mCropView.startCropBitmap(stream, mCameraView.getSensorRotationDegrees(), previewSize.getWidth(), previewSize.getHeight());
                }

                @Override
                public void onError(@NonNull ImageCaptureException exception) {
                    exception.printStackTrace();
                    Log.d(TAG, "哎呀！不知怎么的拍失误了: " + exception.getMessage());
                    showToast("哎呀！不知怎么的拍失误了，再来一次吧~");
                }
            });
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case PERMISSION_REQUEST_CODE_CAMERA:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    initView();
                } else {
                    boolean canAgainRequest = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA);
                    showPermissionAlertDialog(canAgainRequest, PERMISSION_REQUEST_CODE_CAMERA, "拒绝打开相机权限将无法拍照");
                }
                break;
            case PERMISSION_REQUEST_CODE_STORAGE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //这里获取权限后不做处理，让用户再去点拍照按钮
                    Log.d(TAG, "存储权限获取成功，可以去拍美照喽~");
                } else {
                    boolean canAgainRequest = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
                    showPermissionAlertDialog(canAgainRequest, PERMISSION_REQUEST_CODE_STORAGE, "拒绝读取SD卡权限将无法获取照片");
                }
                break;
            default:
                break;
        }
    }

    private void showPermissionAlertDialog(boolean canAgainRequest, int requestCode, String rationale) {
        if (canAgainRequest) {
            new AlertDialog.Builder(this)
                    .setTitle("温馨提示")
                    .setMessage(rationale + "\n是否重新获取？")
                    .setNegativeButton(R.string.cancel, null)
                    .setPositiveButton(R.string.confirm, (dialog, which) -> {
                        if (requestCode == PERMISSION_REQUEST_CODE_CAMERA) {
                            cameraTask();
                        } else if (requestCode == PERMISSION_REQUEST_CODE_STORAGE) {
                            takePictureTask();
                        }
                    })
                    .show();
        } else {
            new AlertDialog.Builder(this)
                    .setTitle("温馨提示")
                    .setMessage(rationale + "\n是否去设置？")
                    .setNegativeButton(R.string.cancel, null)
                    .setPositiveButton(R.string.go_setting, (dialog, which) ->
                            IntentUtils.goAppDetail(this, requestCode))
                    .show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mCameraView != null) {
            mCameraView.onDestroy();
        }
    }

    @Override
    public void onBackPressed() {
        if (cropLayout.getVisibility() == View.VISIBLE && mCameraView.isDestroyed()) {
            cropLayout.setVisibility(View.GONE);
            mCameraView.onCreate();
        } else {
            super.onBackPressed();
        }
    }

    private int requestCodeAlbum = CameraConfig.REQUEST_CODE_ALBUM;
    private OnGalleryListener onGalleryListener = () -> IntentUtils.openAlbum(this, requestCodeAlbum);

    public interface OnGalleryListener {
        /**
         * 相册选择
         */
        void onGallery();
    }

    public void setOnGalleryListener(int requestCode, OnGalleryListener onGalleryListener) {
        this.requestCodeAlbum = requestCode;
        this.onGalleryListener = onGalleryListener;
    }

    private void showToast(String text) {
        if (TextUtils.isEmpty(text)) {
            return;
        }
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == requestCodeAlbum && resultCode == RESULT_OK && data != null) {
            // 获取URI
            Uri uri = data.getData();
            String imgPath = RealPathFromUriUtils.getRealPathFromUri(this, uri);
            Intent intent = new Intent();
            intent.putExtra(CameraConfig.DATA_TAKE_PICTURE_PATH, imgPath);
            intent.putExtra(CameraConfig.DATA_TAKE_TYPE, CameraConfig.DATA_TAKE_ALBUM);
            setResult(RESULT_OK, intent);
            finish();
        } else if (requestCode == PERMISSION_REQUEST_CODE_CAMERA) {
            cameraTask();
        }
    }
}